﻿using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp;
using Volo.Abp.Auditing;
using Microsoft.AspNetCore.Http;

namespace AdminManagement
{
    /// <summary>
    /// EF Core拦截器实现
    /// </summary>
    public sealed class AuditFieldsExtInterceptor : SaveChangesInterceptor
    {
        private static string Name = string.Empty;

        public AuditFieldsExtInterceptor(IHttpContextAccessor _httpContextAccessor)
        {
            if (_httpContextAccessor.HttpContext != null && _httpContextAccessor.HttpContext.User.Identity.IsAuthenticated)
            {
                Name = _httpContextAccessor.HttpContext.User.Identity.Name;
            }
        }

        public override InterceptionResult<int> SavingChanges(DbContextEventData eventData, InterceptionResult<int> result)
        {
            OnSavingChanges(eventData);
            return base.SavingChanges(eventData, result);
        }

        public override ValueTask<InterceptionResult<int>> SavingChangesAsync(DbContextEventData eventData, InterceptionResult<int> result,
            CancellationToken cancellationToken = new CancellationToken())
        {
            OnSavingChanges(eventData);
            return base.SavingChangesAsync(eventData, result, cancellationToken);
        }

        /// <summary>
        /// 拦截器--给扩展字段赋值
        /// </summary>
        /// <param name="eventData"></param>
        private static void OnSavingChanges(DbContextEventData eventData)
        {
            ArgumentNullException.ThrowIfNull(eventData.Context);
            eventData.Context.ChangeTracker.DetectChanges();
            foreach (var entityEntry in eventData.Context.ChangeTracker.Entries())
            {
                //此处无效，Abp底层已经在删除的时候将实体状态修改为Modified
                /*if (entityEntry is { State: EntityState.Deleted, Entity: FullAuditedEntityExt<Guid> softDeleteEntity })
                {
                    softDeleteEntity.DeleterName = Name;
                }*/

                if (entityEntry is { State: EntityState.Added, Entity: FullAuditedEntityExt<Guid> creationAuditedObject })
                {
                    //可以通过反射赋值
                    /*var type = entityEntry.GetType();
                    type.GetProperty(nameof(FullAuditedEntity.CreatorId)).SetValue(creationAuditedObject, Guid.NewGuid());*/

                    creationAuditedObject.CreatorName = Name;
                }

                if (entityEntry is { State: EntityState.Modified, Entity: FullAuditedEntityExt<Guid> editAuditedObject })
                {
                    editAuditedObject.LastModifierName = Name;
                    if (editAuditedObject.IsDeleted)
                    {
                        editAuditedObject.DeleterName = Name;
                    }
                }
            }
        }
    }
}
